package util.form.respuesta;

import util.form.pregunta.Pregunta;
import util.form.pregunta.Restriccion1;
import util.form.respuesta.listener.OnCambioValor1Listener;
import util.form.respuesta.listener.OnInputInvalidoListener;
import util.form.respuesta.listener.OnSetNombre1Listener;
import util.form.respuesta.listener.ValorCommand1;


public abstract class AbstractInput1<C extends AbstractInput1<C>> 
extends AbstractInput<C,Restriccion1,Input1,ValorCommand1>
implements Input1
{
	private String valorPorDefecto = null;	
	
	//private OnGuardar1Listener onGuardarListener;
	//private OnCambioValor1Listener onPrimerSetValor;
	private OnCambioValor1Listener onPostCambioValorListener;
	private OnSetNombre1Listener onSetNombreListener;
	
	private OnCambioValor1Listener onPostCambioValorInternoListener;//protegido
	
	@SuppressWarnings("unchecked")
	//@Override
	public C setNombre(String nombre) throws Exception {
		this.getPregunta().setNombre(nombre);
		if(onSetNombreListener!=null) {
			onSetNombreListener.onSetNombre(this);
		}
		return (C)this;
	}
	
	@Override
	public boolean contieneValor(String valor) {
		String v = this.getValor(); 
		return v!=null && v.equals(valor);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public final C setValor(String valor) throws Exception {
		soloSetValor(valor);					
		onCambioValor(valor);		
		return (C)this;
	}
		
	protected abstract void soloSetValor(String valor) throws Exception;
	
	protected final void onCambioValor() throws Exception {
		onCambioValor(this.getValor());
	}
	
	protected void onCambioValor(String valor) throws Exception {		
		
		if(onPostCambioValorListener!=null)
			onPostCambioValorListener.onCambioValor(valor);		
		
		if(onPostCambioValorInternoListener!=null)
			onPostCambioValorInternoListener.onCambioValor(valor);
	}
	
	@SuppressWarnings("unchecked")
	public C ejecutar(Input1Command comando) throws Exception {
		comando.execute(this);
		return (C)this;
	}

	
	/*
	public void inicializar() throws Exception {
		if(isRelevante()) {
			onCambioValor();
		}
	}
	*/
	
	
	
	/*
	protected final void onCambioValor() throws Exception {
		String v = this.getValor();	
	}
	*/
	
	//@Override
	//public int getValorInt() {
	//	return StringUtil.StringtoInt(getValor());
	//}


	
	@Override
	public final String getValorRelevante() {
		String v = getValor();
		return isRelevante() ? (v==null? valorPorDefecto : v) : null;
	}
	
	
		
	@Override
	public final boolean isValido(OnInputInvalidoListener listener) throws Exception {
		try {
			
			Pregunta p = this.getPregunta();
			
			String v = getValor();
			if(isVacio(v)) {
				if(p.isRequerido()) {
					//requestFocus();//repetido
					throw new InputInvalidoException(p.getMensajeRequerido());
				}
			}
			else {
				validarValor(v);
				
				
				this.getPregunta().validarRestricciones(new String[]{v});
			}			
		}
		catch(InputInvalidoException e) {
			requestFocus();
			
			if(listener!=null)
				listener.onInvalido(e.getMessage());			
			return false;
		}		
		return true;
	}

	protected void validarValor(String valor) throws InputInvalidoException {
		
	}
	
	private boolean isVacio(String valor) {
		return valor==null || valor.trim().isEmpty();
	}

	@Override
	public final boolean isVacio() {
		return isVacio(getValor());
	}
	
	@Override
	public void setMissing() throws Exception {
		//if(isVacio()) {
		setValor(getMissing());
		//}
	}
	
	public String getValorPorDefecto() {
		return valorPorDefecto;
	}

	@SuppressWarnings("unchecked")
	public C setValorPorDefecto(String valorPorDefecto) {
		this.valorPorDefecto = valorPorDefecto;
		return (C)this;
	}
	
	@Override
	protected void soloLectura(boolean soloLectura) {
		
	}
	
	
	
	
	/*
	@SuppressWarnings("unchecked")
	//@Override
	public final C agregarRestriccion(Restriccion1 restriccion) {
		this.restricciones.add(restriccion);
		return (C) this;
	}
	*/
	
	/*
	private void validarRestricciones(String v) throws Exception {
		Restriccion1 r = this.restriccion;
		//for(Restriccion1 r : restricciones) {
			if(r!=null && !r.validar(v)) {
				throw new InputInvalidoException(getPrefijoNombre()+r.getMensajeInvalidez(v));
			}
		//}
	}
	 */

	
	
	/*
	@Override
	public void validarRestricciones() throws Exception {
		validarRestricciones(getValor());
	}*/
	
			
	public OnCambioValor1Listener getOnPostCambioValorListener() {
		return onPostCambioValorListener;
	}

	@SuppressWarnings("unchecked")
	public C setOnPostCambioValorListener(OnCambioValor1Listener onPostCambioValorListener) {
		this.onPostCambioValorListener = onPostCambioValorListener;
		return (C)this;
	}

	protected OnCambioValor1Listener getOnPostCambioValorInternoListener() {
		return onPostCambioValorInternoListener;
	}

	protected void setOnPostCambioValorInternoListener(
			OnCambioValor1Listener onPostCambioValorInternoListener) {
		this.onPostCambioValorInternoListener = onPostCambioValorInternoListener;
	}

	public OnSetNombre1Listener getOnSetNombreListener() {
		return onSetNombreListener;
	}

	public void setOnSetNombreListener(OnSetNombre1Listener onSetNombreListener) {
		this.onSetNombreListener = onSetNombreListener;
	}
	
}
